package com.higgins.eventtracking.client.health;

import java.util.Date;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.higgins.eventtracking.client.DietTrackingService;
import com.higgins.eventtracking.client.DietTrackingServiceAsync;
import com.higgins.eventtracking.client.dto.MealDTO;
import com.higgins.eventtracking.client.health.components.GenericChartPanel;
import com.higgins.eventtracking.client.health.components.GenericTabInterface;

public class Diet extends VerticalPanel	implements GenericTabInterface		{
	private List<MealDTO> meals;
	final ListBox mealListBox = new ListBox();
	final ListBox meatListBox = new ListBox();
	final ListBox carbsListBox = new ListBox();
	final ListBox vegListBox = new ListBox();
	final ListBox snackListBox = new ListBox();
	final ListBox drinkListBox = new ListBox();
	final Label whatsGoingOn = new Label();
	final Label caloriesToday = new Label();
	final Label proteinToday = new Label();
	final Label fatToday = new Label();
	final Label waterToday = new Label();
		
	final Label textToServerLabel = new Label();
	final HTML serverResponseLabel = new HTML();
	final DialogBox dialogBox = new DialogBox();
	final Button closeButton = new Button("Close");
	final Label errorLabel = new Label();

	private final DietTrackingServiceAsync dietTrackingService = GWT
	.create(DietTrackingService.class);
	private boolean firstRun = true;
	private Integer tabIndex = null;
	private String tabTitle = null;
	
	@Override
	public Integer getTabIndex() {
		return tabIndex;
	}
	@Override
	public void setTabIndex(Integer index) {
		this.tabIndex = index;
	}
	@Override
	public String getTabTitle()	{
		return tabTitle;
	}
	@Override
	public void setTabTitle(String tabTitle)	{
		this.tabTitle = tabTitle;
	}

	public Diet()	{
	}
	public void update()	{
		if (firstRun)
			initialise();
	}
	public void initialise()	{
		addDialogBox();
		addListBoxes();
		loadMealList();
		addHandlers();
		loadStats();
		firstRun = false;
	}
	
	private void addListBoxes()	{
		FlowPanel flowPanel = new FlowPanel();
		VerticalPanel mealsPanel = new VerticalPanel();
		mealsPanel.add(new Label("Meals:"));
		mealsPanel.add(mealListBox);
		flowPanel.add(mealsPanel);

		VerticalPanel drinksPanel = new VerticalPanel();
		drinksPanel.add(new Label("Drinks:"));
		drinksPanel.add(drinkListBox);
		flowPanel.add(drinksPanel);
		
		VerticalPanel snacksPanel = new VerticalPanel();
		snacksPanel.add(new Label("Snacks:"));
		snacksPanel.add(snackListBox);
		flowPanel.add(snacksPanel);
		
		VerticalPanel meatsPanel = new VerticalPanel();
		meatsPanel.add(new Label("Meat:"));
		meatsPanel.add(meatListBox);
		flowPanel.add(meatsPanel);

		VerticalPanel carbsPanel = new VerticalPanel();
		carbsPanel.add(new Label("Carbs:"));
		carbsPanel.add(carbsListBox);
		flowPanel.add(carbsPanel);

		VerticalPanel vegPanel = new VerticalPanel();
		vegPanel.add(new Label("Veg:"));
		vegPanel.add(vegListBox);
		flowPanel.add(vegPanel);


		
		add(flowPanel);
		add(whatsGoingOn);
		add(caloriesToday);
		add(proteinToday);
		add(fatToday);
		add(waterToday);
		
	}
	private void loadMealList()	{
		dietTrackingService.retrieveMeals(new AsyncCallback<List<MealDTO>>() {
					public void onFailure(Throwable caught) {
						mealListBox.addItem("FAILURE");
					}

					public void onSuccess(List<MealDTO> result) {
						meals = result;
						Integer index = 0;
						for (MealDTO dto:result)	{
							if (dto.getType()==null)
							{		}
							else if (dto.getType().equals("Meal"))	{
								mealListBox.addItem(dto.getMeal(), index.toString());
							}
							else if (dto.getType().equals("Meat"))	{
								meatListBox.addItem(dto.getMeal(), index.toString());
							}
							else if (dto.getType().equals("Veg"))	{
								vegListBox.addItem(dto.getMeal(), index.toString());
							}
							else if (dto.getType().equals("Carbs"))	{
								carbsListBox.addItem(dto.getMeal(), index.toString());
							}
							else if (dto.getType().equals("Snack"))	{
								snackListBox.addItem(dto.getMeal(), index.toString());
							}
							else if (dto.getType().equals("Drink"))	{
								drinkListBox.addItem(dto.getMeal(), index.toString());
							}
							index++;
						}
						setListBoxesToDeSelected();
					}
				});
	}
	
	private void loadStats()	{
		dietTrackingService.retrieveCaloriesToday(new AsyncCallback<Double>() {
			public void onFailure(Throwable caught) {
				whatsGoingOn.setText("Unable to retrieve Calories Today");
			}

			public void onSuccess(Double result) {
				caloriesToday.setText("Calories: " + result + " 	(" + Math.round(100*result/3000) + " % of 3,000)");
			}});	
		dietTrackingService.retrieveProteinToday(new AsyncCallback<Double>() {
			public void onFailure(Throwable caught) {
				whatsGoingOn.setText("Unable to retrieve Protein Today");
			}

			public void onSuccess(Double result) {
				proteinToday.setText("Protein: " + result+ " 	(" + Math.round(100*result/180) + " % of 180)");
			}});	
		dietTrackingService.retrieveFatToday(new AsyncCallback<Double>() {
			public void onFailure(Throwable caught) {
				whatsGoingOn.setText("Unable to retrieve Fat Today");
			}

			public void onSuccess(Double result) {
				fatToday.setText("Fat: " + result+ " 	(" + Math.round(100*result/100) + " % of 100??)");
			}});	
		dietTrackingService.retrieveWaterToday(new AsyncCallback<Double>() {
			public void onFailure(Throwable caught) {
				whatsGoingOn.setText("Unable to retrieve Water Today");
			}

			public void onSuccess(Double result) {
				waterToday.setText("Water: " + result+ " 	(" + Math.round(100*result/2000) + " % of 2,000)");
			}});			
	}
	
	private void setListBoxesToDeSelected()	{
		mealListBox.setSelectedIndex(-1);
		meatListBox.setSelectedIndex(-1);
		carbsListBox.setSelectedIndex(-1);
		vegListBox.setSelectedIndex(-1);
		snackListBox.setSelectedIndex(-1);
		drinkListBox.setSelectedIndex(-1);
	}
	
	private void addDialogBox()	{
		dialogBox.setText("Remote Procedure Call");
		dialogBox.setAnimationEnabled(true);
		// We can set the id of a widget by accessing its Element
		closeButton.getElement().setId("closeButton");
		VerticalPanel dialogVPanel = new VerticalPanel();
		dialogVPanel.addStyleName("dialogVPanel");
		dialogVPanel.add(new HTML("<b>Sending name to the server:</b>"));
		dialogVPanel.add(textToServerLabel);
		dialogVPanel.add(new HTML("<br><b>Server replies:</b>"));
		dialogVPanel.add(serverResponseLabel);
		dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
		dialogVPanel.add(closeButton);
		dialogBox.setWidget(dialogVPanel);

		// Add a handler to close the DialogBox
		closeButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				dialogBox.hide();
			}
		});		
	}
	
	private void addHandlers()	{
		class MyHandler implements ChangeHandler {	
			ListBox listBox;
			
			public void setListBox(ListBox listBox)	{
				this.listBox = listBox;
			}
			@Override
			public void onChange(ChangeEvent event) {
				int selectedIndex = listBox.getSelectedIndex();
				setListBoxesToDeSelected();
				listBox.setSelectedIndex(selectedIndex);
				
				Integer index = Integer.parseInt(listBox.getValue(selectedIndex));
				MealDTO meal = meals.get(index);
				String mealStr = meal!=null?meal.getMeal():"MEAL IS NULL";
				if (index == null)	
					index = -1;
				if (mealStr == null)
					mealStr = "NULL";
				whatsGoingOn.setText("Selected: " + index + ", " + mealStr);
				dietTrackingService.insertConsumption(new Date(), meal.getMeal(), meal.getCalories(), meal.getProtein(), 
						meal.getFat(), meal.getWater(), new AsyncCallback<Boolean>() {
					public void onFailure(Throwable caught) {
						whatsGoingOn.setText("Not Written");
						setListBoxesToDeSelected();
					}

					public void onSuccess(Boolean result) {
						setListBoxesToDeSelected();
						whatsGoingOn.setText("Successfully Written");
						loadStats();
					}});
			}
		}
		MyHandler mealListBoxHandler = new MyHandler();
		mealListBoxHandler.setListBox(mealListBox);
		MyHandler meatListBoxHandler = new MyHandler();
		meatListBoxHandler.setListBox(meatListBox);
		MyHandler carbsListBoxHandler = new MyHandler();
		carbsListBoxHandler.setListBox(carbsListBox);
		MyHandler vegListBoxHandler = new MyHandler();
		vegListBoxHandler.setListBox(vegListBox);
		MyHandler snackListBoxHandler = new MyHandler();
		snackListBoxHandler.setListBox(snackListBox);
		MyHandler drinkListBoxHandler = new MyHandler();
		drinkListBoxHandler.setListBox(drinkListBox);
		
		mealListBox.addChangeHandler(mealListBoxHandler);
		meatListBox.addChangeHandler(meatListBoxHandler);
		carbsListBox.addChangeHandler(carbsListBoxHandler);
		vegListBox.addChangeHandler(vegListBoxHandler);
		snackListBox.addChangeHandler(snackListBoxHandler);
		drinkListBox.addChangeHandler(drinkListBoxHandler);
	}
	@Override
	public void addChartPanel(GenericChartPanel chartPanel) {
		// TODO Auto-generated method stub
		
	}	

}
